package com.fw.ui.view.common;

import static org.springframework.beans.factory.config.BeanDefinition.SCOPE_PROTOTYPE;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import com.fw.ui.util.VaadinApplicationObjectSupport;
import com.fw.ui.util.comparator.StringComparator;
import com.fw.ui.view.AbstractPanel;
import com.fw.ui.view.common.event.TwinListSelectPanelAddButtonClickListener;
import com.fw.ui.view.common.event.TwinListSelectPanelAvailableSelectedTextChangeListener;
import com.fw.ui.view.common.event.TwinListSelectPanelCurrentSelectedTextChangeListener;
import com.fw.ui.view.common.event.TwinListSelectPanelRemoveButtonClickListener;
import com.vaadin.shared.ui.label.ContentMode;
import com.vaadin.ui.Alignment;
import com.vaadin.ui.Button;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.Label;
import com.vaadin.ui.ListSelect;
import com.vaadin.ui.TextField;
import com.vaadin.ui.VerticalLayout;

@Component
@Scope(SCOPE_PROTOTYPE)
public class TwinListSelectPanel extends AbstractPanel {

    private static final long serialVersionUID = 2801175323310209618L;

    @Autowired
    protected transient VaadinApplicationObjectSupport app;
    @Autowired
    private TwinListSelectPanelAddButtonClickListener twinListSelectPanelAddButtonClickListener;
    @Autowired
    private TwinListSelectPanelAvailableSelectedTextChangeListener twinListSelectPanelAvailableSelectedTextChangeListener;
    @Autowired
    private TwinListSelectPanelCurrentSelectedTextChangeListener twinListSelectPanelCurrentSelectedTextChangeListener;
    @Autowired
    private TwinListSelectPanelRemoveButtonClickListener twinListSelectPanelRemoveButtonClickListener;

    private HorizontalLayout rowLayout = new HorizontalLayout();
    private VerticalLayout col1Layout = new VerticalLayout();
    private VerticalLayout col2Layout = new VerticalLayout();
    private VerticalLayout col3Layout = new VerticalLayout();

    private Label lblAvailable = new Label();
    private Label lblCurrentSelect = new Label();
    private TextField txtAvailable = new TextField();
    private TextField txtCurrentSelected = new TextField();
    private ListSelect selectAvailable = new ListSelect();
    private ListSelect selectCurrent = new ListSelect();
    private Button btnAdd = new Button();
    private Button btnRemove = new Button();

    private Map<Object, String> availableMap = new HashMap<Object, String>();
    private Map<Object, String> currentSelectedMap = new HashMap<Object, String>();

    public void init() {
	this.setSizeUndefined();

	VerticalLayout vLayout = (VerticalLayout) this.getContent();
	vLayout.setSizeUndefined();

	this.rowLayout.setSizeUndefined();
	this.rowLayout.setSpacing(true);
	this.col1Layout.setWidth("250px");
	this.col1Layout.setSpacing(true);
	this.col2Layout.setWidth("100px");
	this.col2Layout.setSpacing(true);
	this.col3Layout.setWidth("250px");
	this.col3Layout.setSpacing(true);

	this.txtAvailable.setWidth("100%");
	this.selectAvailable.setRows(12);
	this.selectAvailable.setSizeFull();
	this.selectAvailable.setMultiSelect(true);
	this.selectAvailable.setNullSelectionAllowed(false);
	this.col1Layout.addComponent(this.lblAvailable);
	this.col1Layout.addComponent(this.txtAvailable);
	this.col1Layout.addComponent(this.selectAvailable);
	this.rowLayout.addComponent(this.col1Layout);

	this.btnAdd.setCaption("Add");
	this.btnAdd.setWidth("80px");
	this.btnRemove.setCaption("Remove");
	this.btnRemove.setWidth("80px");
	this.col2Layout.addComponent(this.btnAdd);
	this.col2Layout.addComponent(this.btnRemove);
	this.col2Layout.setComponentAlignment(this.btnAdd, Alignment.MIDDLE_CENTER);
	this.col2Layout.setComponentAlignment(this.btnRemove, Alignment.MIDDLE_CENTER);
	this.rowLayout.addComponent(this.col2Layout);
	this.rowLayout.setComponentAlignment(this.col2Layout, Alignment.MIDDLE_CENTER);

	this.txtCurrentSelected.setWidth("100%");
	this.selectCurrent.setRows(12);
	this.selectCurrent.setSizeFull();
	this.selectCurrent.setMultiSelect(true);
	this.selectCurrent.setNullSelectionAllowed(false);
	this.col3Layout.addComponent(this.lblCurrentSelect);
	this.col3Layout.addComponent(this.txtCurrentSelected);
	this.col3Layout.addComponent(this.selectCurrent);
	this.rowLayout.addComponent(this.col3Layout);

	vLayout.addComponent(this.rowLayout);
    }

    public void setListSelectData(Map<Object, String> map, ListSelect listSelect) {
	listSelect.removeAllItems();
	if (map != null && !map.isEmpty()) {
	    List<String> captions = new ArrayList<String>(map.values());
	    Collections.sort(captions, new StringComparator(true));
	    for (String caption : captions) {
		Set<Object> keySet = map.keySet();
		Iterator<Object> keyIterator = keySet.iterator();
		while (keyIterator.hasNext()) {
		    Object key = keyIterator.next();
		    String str = map.get(key);
		    if (str.equals(caption)) {
			listSelect.addItem(key);
			listSelect.setItemCaption(key, str);
			break;
		    }
		}
	    }
	}
    }

    public void setAvailableList(Map<Object, String> availableMap) {
	this.availableMap = availableMap;
	this.setListSelectData(availableMap, this.selectAvailable);
	this.txtAvailable.setValue("");
    }

    public Collection<Object> getAvailableList() {
	return (Collection<Object>) this.availableMap.keySet();
    }

    public void setCurrentSelectedList(Map<Object, String> currentSelectedMap) {
	this.currentSelectedMap = currentSelectedMap;
	this.setListSelectData(currentSelectedMap, this.selectCurrent);
	this.txtCurrentSelected.setValue("");
    }

    public Collection<Object> getCurrentSelectedList() {
	return (Collection<Object>) this.currentSelectedMap.keySet();
    }

    public void setPanelTitle(String title) {
	this.setCaption(title);
    }

    public void setAvailableTitle(String title) {
	this.lblAvailable.setContentMode(ContentMode.HTML);
	this.lblAvailable.setValue("<strong>" + title + "</strong>");
    }

    public void setCurrentSelectedTitle(String title) {
	this.lblCurrentSelect.setContentMode(ContentMode.HTML);
	this.lblCurrentSelect.setValue("<strong>" + title + "</strong>");
    }

    public void clearForm() {
	this.txtAvailable.setValue("");
	this.txtCurrentSelected.setValue("");
	this.selectAvailable.removeAllItems();
	this.selectCurrent.removeAllItems();
	this.availableMap.clear();
	this.currentSelectedMap.clear();
    }

    @Override
    public void initListener() {
	this.twinListSelectPanelAddButtonClickListener.setBasedComponent(this);
	this.twinListSelectPanelAvailableSelectedTextChangeListener.setBasedComponent(this);
	this.twinListSelectPanelCurrentSelectedTextChangeListener.setBasedComponent(this);
	this.twinListSelectPanelRemoveButtonClickListener.setBasedComponent(this);

	this.txtAvailable.addTextChangeListener(this.twinListSelectPanelAvailableSelectedTextChangeListener);
	this.txtCurrentSelected.addTextChangeListener(this.twinListSelectPanelCurrentSelectedTextChangeListener);
	this.btnAdd.addClickListener(this.twinListSelectPanelAddButtonClickListener);
	this.btnRemove.addClickListener(this.twinListSelectPanelRemoveButtonClickListener);
    }

    @Override
    public void initValidator() {
	// TODO Auto-generated method stub

    }

    public TextField getTxtAvailable() {
	return txtAvailable;
    }

    public void setTxtAvailable(TextField txtAvailable) {
	this.txtAvailable = txtAvailable;
    }

    public TextField getTxtCurrentSelected() {
	return txtCurrentSelected;
    }

    public void setTxtCurrentSelected(TextField txtCurrentSelected) {
	this.txtCurrentSelected = txtCurrentSelected;
    }

    public Map<Object, String> getAvailableMap() {
	return availableMap;
    }

    public void setAvailableMap(Map<Object, String> availableMap) {
	this.availableMap = availableMap;
    }

    public Map<Object, String> getCurrentSelectedMap() {
	return currentSelectedMap;
    }

    public void setCurrentSelectedMap(Map<Object, String> currentSelectedMap) {
	this.currentSelectedMap = currentSelectedMap;
    }

    public ListSelect getSelectAvailable() {
	return selectAvailable;
    }

    public void setSelectAvailable(ListSelect selectAvailable) {
	this.selectAvailable = selectAvailable;
    }

    public ListSelect getSelectCurrent() {
	return selectCurrent;
    }

    public void setSelectCurrent(ListSelect selectCurrent) {
	this.selectCurrent = selectCurrent;
    }

    public Button getBtnAdd() {
	return btnAdd;
    }

    public void setBtnAdd(Button btnAdd) {
	this.btnAdd = btnAdd;
    }

    public Button getBtnRemove() {
	return btnRemove;
    }

    public void setBtnRemove(Button btnRemove) {
	this.btnRemove = btnRemove;
    }

    @Override
    public void initData() {
	// TODO Auto-generated method stub
	
    }

    @Override
    public void updateStrings() {
	// TODO Auto-generated method stub
	
    }

}
